hiloArray
Arrays Sandbox PanosP Revised

Finding the Largest or Smallest Valued Element in an Array

Problem
=======

Given an array, find the largest or smallest valued element.

Solution
========

First we'll find the largest element of an array containig numbers.
We must be careful not to let awk compare the array elements as
strings, because 2 will be considered greater than 10 if compared
as strings.

 function findMaxNum(arr,			i, max) {
 	for (i in arr) {
 		if ((arr[i] + 0) > (max + 0))
 			max = arr[i]
 	}
 	return(max)
 }

To find the smallest number valued element is similar:

 function findMinNum(arr,			i, min) {
 	for (i in arr) {
 		if ((arr[i] + 0) < (min + 0))
 			min = arr[i]
 	}
 	return(min)
 }

None of the above functions behave well when passed
an empty array. Also, array elements that are not pure numbers,
e.g. "123abc", may produce problems or erroneus results. The
only precaution taken by the functions above is to add number
zero to both array elements and to current max or min items
to enforce number comparison.

Now let's develop a more sophisticated function to seek
the "largest" or "smallest" value of arrays of any type.
Assuming array values are in the form of _lastname_:_firstname_:_nsn_,
e.g. `Papadopoulos:Panos:032792320`, `Menzies:Tim:782445800`, etc.
We want the largest element based on `nsn` (national security number).
It would be nice to provide a _comparison_ function as an argument.
That function may take as arguments the array and two
indices to compare the correspondig elements, and return -1, 0,
or 1 when the first element is "lower" than the second,
0 if the two elements are of the same value, and 1
if the first element is greater than the second:

 function findMax(arr, cmp,		i, maxi) {
 	for (i in arr) {
 		if (maxi == "")
 			maxi = i
 		else if (cmp(arr, i, maxi) > 0)
 			maxi = i
 	}
 	return(maxi)
 }

 function cmp(arr, i, j,			a, ai) {
 	split(arr[i], ":", a)
 	ai = a[3]
 	split(arr[j], ":", a)
 	if (ai < a[3])
 		return(-1)
 	if (ai > a[3])
 		return(1)
 	return(0)
  }

Arnold Robins, the main gawk maintainer,
is working on that issue
([?http://www.eggheadcafe.com/software/aspnet/35699599/indirect-function-calls-p.aspx]),
but for the time being *there is no such thing as function pointers or so in awk*.
So we must supply the comparison procedure as
part of the main function:

  function findMaxPerson(arr,	i, maxi, maxssn, a) {
  	for (i in arr) {
  		split(arr[i], ":", a)
  		if (maxi == "") {
  			maxssn = a[3]
  			maxi = i
  		}
  		else if (a[3] > maxssn) {
  			maxssn = a[3]
  			maxi = i
  		}
  	}
  	return(maxi)
   }

Discussion
==========

We must be careful for arrays with empty indexed items.
If that's the case, then the `(maxi == "")` check must change.

Author
======

Panos Papadopoulos

